from django.shortcuts import render
from threading import Thread
from dwebsocket.decorators import accept_websocket
import paramiko

def make_ssh(host="39.106.219.123", username="root", password="zst030528", port=22):
    """
    @host: 主机地址
    @username: 用户名，一般是root
    @password: 密码
    @port: ssh协议的端口,22
    """
    # 初始化一个ssh对象
    sh = paramiko.SSHClient()
    # 设置对象连接密钥规则
    sh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 连接
    sh.connect(host, username=username, password=password, port=port)
    # 生成shell对象
    channel = sh.invoke_shell(term='xterm')
    return channel

def recv_ssh_msg(channel, ws):
    # 判断shell连接对象是否没有退出
    while not channel.exit_status_ready():
        # 接收过程可能会因为没有任何返回而报错
        try:
            buf = channel.recv(1024)  # 接收命令的执行结果
            ws.send(buf)  # 向Websocket通道返回
        # 接收不到会报错，但是报错没关系，继续重新尝试接受
        except:
            break

@accept_websocket
def webssh(request):
    if request.is_websocket:
        # 1. 获取到连接对象
        ws = request.websocket
        # 2. 初始化linux连接, 即调用连接远程服务器方法
        channel = make_ssh()
        # 3. 初始化linux数据接收线程，并开启
        recv_thread = Thread(target=recv_ssh_msg, args=(channel, ws))
        recv_thread.start()
        while 1:  # 主线程: 只管发送
            cmd = ws.wait()  # 阻塞ws接收发来的数据
            if cmd:
                channel.send(cmd)  # 发送到linux 去执行
            else:  # 如果连接断开，那么cmd将会发一个空包
                break
        recv_thread.join()  # 回收子线程
        ws.close()  # 关闭ws连接